An array's length should be cached to save gas in for-loops #288
Labels
bug
Something isn't working
duplicate
This issue or pull request already exists
G (Gas Optimization)
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Handle
Dravee
Vulnerability details
Impact
Increased gas cost
Proof of Concept
(As seen on this contest: code-423n4/2021-10-slingshot-findings#63)
Reading array length at each iteration of the loop takes 6 gas (3 for mload and 3 to place memory_offset) in the stack.
Caching the array length in the stack saves around 3 gas per iteration.
Instances include:
RebalanceManager.sol#rebalance()
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/callManagers/RebalanceManager.sol#L218
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/callManagers/RebalanceManager.sol#L234
RebalanceManagerV2.sol#rebalance()
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/callManagers/RebalanceManagerV2.sol#L155
RebalanceManagerV3.sol#rebalance()
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/callManagers/RebalanceManagerV3.sol#L166
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/callManagers/RebalanceManagerV3.sol#L171
BasketFacet.sol#removeToken
,BasketFacet.sol#joinPool
,BasketFacet.sol#exitPool
,BasketFacet.sol#getTokens
,BasketFacet.sol#calcTokensForAmount
,BasketFacet.sol#calcTokensForAmountExit
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/facets/Basket/BasketFacet.sol#L50
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/facets/Basket/BasketFacet.sol#L160
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/facets/Basket/BasketFacet.sol#L202
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/facets/Basket/BasketFacet.sol#L321
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/facets/Basket/BasketFacet.sol#L348
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/facets/Basket/BasketFacet.sol#L381
CallFacet.sol#call
,CallFacet.sol#removeCaller
,CallFacet.sol#callNoValue
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/facets/Call/CallFacet.sol#L55
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/facets/Call/CallFacet.sol#L82
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/facets/Call/CallFacet.sol#L95
SingleNativeTokenExit.sol#exitEth
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleNativeTokenExit.sol#L69
SingleNativeTokenExitV2.sol#_exit
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleNativeTokenExitV2.sol#L74
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleNativeTokenExitV2.sol#L76
SingleTokenJoin.sol#_joinTokenSingle
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleTokenJoin.sol#L108
SingleTokenJoinV2.sol#_joinTokenSingle
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleTokenJoinV2.sol#L86
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleTokenJoinV2.sol#L91
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleTokenJoinV2.sol#L100
https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleTokenJoinV2.sol#L117
Tools Used
VS Code
Recommended Mitigation Steps
Store the array's length in a variable before the for-loop, and use it instead.
The text was updated successfully, but these errors were encountered: