code-423n4 / 2021-12-yetifinance-findings

0 stars 0 forks source link

An array's length should be cached to save gas in for-loops #166

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

Handle

Dravee

Vulnerability details

Impact

Increased gas cost

Proof of Concept

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:

./ActivePool.sol:133:        for (uint i = 0; i < poolColl.tokens.length; i++) {
./ActivePool.sol:167:        for (uint i = 0; i < _tokens.length; i++) {
./ActivePool.sol:184:        for (uint i = 0; i < _tokens.length; i++) {
./BorrowerOperations.sol:699:        for (uint256 i = 0; i < _tokensIn.length; i++) {
./BorrowerOperations.sol:873:        for (uint256 i = 0; i < _colls.length; i++) {
./BorrowerOperations.sol:890:        for (uint256 i = 0; i < arr.length; i++) {
./BorrowerOperations.sol:920:        for (uint256 i = 0; i < _colls1.length; i++) {
./BorrowerOperations.sol:921:            for (uint256 j = 0; j < _colls2.length; j++) {
./BorrowerOperations.sol:929:        for (uint256 i = 0; i < _colls.length; i++) {
./BorrowerOperations.sol:930:            for (uint256 j = i + 1; j < _colls.length; j++) {
./BorrowerOperations.sol:1061:        for (uint i = 0; i < _routers.length; i++) {
./BorrowerOperations.sol:1068:        for (uint i = 0; i < _indices.length - 1; i++) {
./DefaultPool.sol:97:        for (uint256 i = 0; i < poolColl.tokens.length; i++) {
./DefaultPool.sol:133:        for (uint256 i = 0; i < _tokens.length; i++) {
./Dependencies/LiquityBase.sol:63:        for (uint i = 0; i < _coll.tokens.length; i++) {
./Dependencies/LiquityBase.sol:97:        for (uint i = 0; i < _tokens.length; i++) {
./Dependencies/LiquityBase.sol:106:        for (uint i = 0; i < _colls.tokens.length; i++) {
./Dependencies/LiquityBase.sol:115:        for (uint i = 0; i < _colls.tokens.length; i++) {
./Dependencies/LiquityBase.sol:149:        for (uint i = 0; i < tokens.length; i++) {
./Dependencies/LiquityBase.sol:158:        for (uint i = 0; i < coll.tokens.length; i++) {
./Dependencies/LiquityBase.sol:168:        for (uint i = 0; i < _coll.tokens.length; i++) {
./Dependencies/YetiCustomBase.sol:36:        for (uint256 i = 0; i < _coll1.tokens.length; i++) {
./Dependencies/YetiCustomBase.sol:44:        for (uint256 i = 0; i < _coll2.tokens.length; i++) {
./Dependencies/YetiCustomBase.sol:59:        for (uint256 i = 0; i < coll3.tokens.length; i++) {
./Dependencies/YetiCustomBase.sol:104:        for (uint256 i = 0; i < _tokens.length; i++) {
./Dependencies/YetiCustomBase.sol:122:        for (uint256 i = 0; i < _subTokens.length; i++) {
./Dependencies/YetiCustomBase.sol:144:        for (uint256 i = 0; i < _coll1.tokens.length; i++) {
./Dependencies/YetiCustomBase.sol:152:        for (uint256 i = 0; i < _tokens.length; i++) {
./Dependencies/YetiCustomBase.sol:165:        for (uint256 i = 0; i < coll3.tokens.length; i++) {
./Dependencies/YetiCustomBase.sol:178:        for (uint i = 0; i < _arr.length; i++) {
./HintHelpers.sol:139:        for (uint256 i = 0; i < colls.tokens.length; i++) {
./MultiTroveGetter.sol:110:        for (uint i = 0; i < data.allColls.length; i++) {
./StabilityPool.sol:562:        for (uint256 i = 0; i < _amountsAdded.length; i++) {
./StabilityPool.sol:588:        for (uint256 i = 0; i < _amountsAdded.length; i++) {
./StabilityPool.sol:592:        for (uint256 i = 0; i < _amountsAdded.length; i++) {
./StabilityPool.sol:628:        for (uint256 i = 0; i < _assets.length; i++) {
./StabilityPool.sol:720:        for (uint256 i = 0; i < assets.length; i++) {
./StabilityPool.sol:942:        for (uint256 i = 0; i < assets.length; i++) {
./StabilityPool.sol:994:            for (uint256 i = 0; i < colls.length; ++i) {
./StabilityPool.sol:1011:        for (uint256 i = 0; i < allColls.length; i++) {
./TroveManager.sol:234:        for (uint i = 0; i < _lowerHints.length; i++) {
./TroveManager.sol:348:        for (uint i = 0; i < allColls.length; i++) {
./TroveManager.sol:374:        for (uint i = 0; i < allColls.length; i++ ) {
./TroveManager.sol:397:        for (uint i = 0; i < allColls.length; i++ ) {
./TroveManager.sol:420:        for (uint i = 0; i < assets.length; i++) {
./TroveManager.sol:460:        for (uint i = 0; i < borrowerColls.length; i++) {
./TroveManager.sol:476:        for (uint i = 0; i < Troves[_borrower].colls.tokens.length; i++) {
./TroveManager.sol:525:        for (uint i = 0; i < _tokens.length; i++) {
./TroveManager.sol:582:        for (uint i = 0; i < allColls.length; i++) {
./TroveManager.sol:603:        for (uint i = 0; i < _tokens.length; i++) {
./TroveManagerLiquidations.sol:255:        for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {
./TroveManagerLiquidations.sol:334:        for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {
./TroveManagerLiquidations.sol:394:        for (uint256 i = 0; i < vars.collToLiquidate.tokens.length; i++) {
./TroveManagerLiquidations.sol:475:        for (uint256 i = 0; i < vars.collToLiquidate.tokens.length; i++) {
./TroveManagerLiquidations.sol:701:            for (uint256 i = 0; i < _collsToLiquidate.tokens.length; i++) {
./TroveManagerLiquidations.sol:721:            for (uint256 i = 0; i < _collsToLiquidate.tokens.length; i++) {
./TroveManagerLiquidations.sol:808:        for (uint i = 0; i < _troveTokens.length; i++) {
./TroveManagerLiquidations.sol:840:        for (uint i = 0; i < _colls.tokens.length; i++) {
./TroveManagerRedemptions.sol:304:        for (uint256 i = 0; i < colls.tokens.length; i++) {
./TroveManagerRedemptions.sol:367:            for (uint256 i = 0; i < colls.tokens.length; i++) {
./TroveManagerRedemptions.sol:517:        for (uint256 i = 0; i < coll.amounts.length; i++) {
./YETI/BoringCrypto/BoringBatchable.sol:37:        for (uint256 i = 0; i < calls.length; i++) {

Tools Used

VS Code

Recommended Mitigation Steps

Store the array's length in a variable before the for-loop, and use it instead.

kingyetifinance commented 2 years ago

@LilYeti : Duplicate #14

alcueca commented 2 years ago

Duplicate #283