From 68151295d45681be62916abf3b8479866e7fe1d9 Mon Sep 17 00:00:00 2001 From: theakalord Date: Sun, 1 Sep 2024 20:51:41 -0400 Subject: [PATCH] refactor: optimize gas for for loops --- contracts/offchain-helpers/PendleMulticallV1.sol | 4 ++-- contracts/offchain-helpers/PendleMulticallV2.sol | 6 +++--- contracts/router/ActionMiscV3.sol | 14 +++++++++----- contracts/router/ActionStorageV4.sol | 6 ++++-- .../kyberswap/l1-contracts/InputScalingHelper.sol | 6 +++--- .../kyberswap/l2-contracts/CalldataReader.sol | 6 +++--- .../kyberswap/l2-contracts/CalldataWriter.sol | 14 +++++++------- .../kyberswap/l2-contracts/Common.sol | 2 +- .../kyberswap/l2-contracts/ExecutorReader.sol | 4 ++-- .../l2-contracts/InputScalingHelperL2.sol | 6 +++--- 10 files changed, 37 insertions(+), 31 deletions(-) diff --git a/contracts/offchain-helpers/PendleMulticallV1.sol b/contracts/offchain-helpers/PendleMulticallV1.sol index 8e0c9cb4..c02fcb43 100644 --- a/contracts/offchain-helpers/PendleMulticallV1.sol +++ b/contracts/offchain-helpers/PendleMulticallV1.sol @@ -15,7 +15,7 @@ contract PendleMulticallV1 { function aggregate(Call[] calldata calls) public payable virtual { uint256 length = calls.length; Call calldata call; - for (uint256 i = 0; i < length; ) { + for (uint256 i; i != length; ) { call = calls[i]; (bool success, bytes memory resp) = call.target.call(call.callData); @@ -39,7 +39,7 @@ contract PendleMulticallV1 { uint256 length = calls.length; returnData = new Result[](length); Call calldata call; - for (uint256 i = 0; i < length; ) { + for (uint256 i; i != length; ) { call = calls[i]; (bool success, bytes memory resp) = call.target.call{gas: gasLimit}(calls[i].callData); diff --git a/contracts/offchain-helpers/PendleMulticallV2.sol b/contracts/offchain-helpers/PendleMulticallV2.sol index ca4ae8eb..4bf6911e 100644 --- a/contracts/offchain-helpers/PendleMulticallV2.sol +++ b/contracts/offchain-helpers/PendleMulticallV2.sol @@ -17,7 +17,7 @@ contract PendleMulticallV2 { function aggregate(Call[] calldata calls) public payable virtual { uint256 length = calls.length; Call calldata call; - for (uint256 i = 0; i < length; ) { + for (uint256 i; i != length; ) { call = calls[i]; (bool success, bytes memory resp) = call.target.call(call.callData); @@ -41,7 +41,7 @@ contract PendleMulticallV2 { uint256 length = calls.length; returnData = new Result[](length); Call calldata call; - for (uint256 i = 0; i < length; ) { + for (uint256 i; i != length; ) { call = calls[i]; (bool success, bytes memory resp) = call.target.call{gas: gasLimit}(calls[i].callData); @@ -66,7 +66,7 @@ contract PendleMulticallV2 { uint256 length = calls.length; returnData = new bytes[](length); Call calldata call; - for (uint256 i = 0; i < length; ) { + for (uint256 i; i != length; ) { call = calls[i]; (, returnData[i]) = address(this).delegatecall{gas: gasLimit}( diff --git a/contracts/router/ActionMiscV3.sol b/contracts/router/ActionMiscV3.sol index 88a88d0d..4c4ec59c 100644 --- a/contracts/router/ActionMiscV3.sol +++ b/contracts/router/ActionMiscV3.sol @@ -80,15 +80,18 @@ contract ActionMiscV3 is IPActionMiscV3, ActionBase { address[] calldata yts, address[] calldata markets ) external { - for (uint256 i = 0; i < sys.length; ++i) { + uint256 length = sys.length; + for (uint256 i; i != length; ++i) { IStandardizedYield(sys[i]).claimRewards(user); } - for (uint256 i = 0; i < yts.length; ++i) { + length = yts.length; + for (uint256 i; i != length; ++i) { IPYieldToken(yts[i]).redeemDueInterestAndRewards(user, true, true); } - for (uint256 i = 0; i < markets.length; ++i) { + length = markets.length; + for (uint256 i; i != length; ++i) { IPMarket(markets[i]).redeemRewards(user); } } @@ -259,7 +262,8 @@ contract ActionMiscV3 is IPActionMiscV3, ActionBase { // ----------------- MISC FUNCTIONS ----------------- function boostMarkets(address[] memory markets) external { - for (uint256 i = 0; i < markets.length; i++) { + uint256 length = markets.length; + for (uint256 i; i != length; ++i) { IPMarket(markets[i]).transferFrom(msg.sender, markets[i], 0); } } @@ -267,7 +271,7 @@ contract ActionMiscV3 is IPActionMiscV3, ActionBase { function multicall(Call3[] calldata calls) external payable returns (Result[] memory res) { uint256 length = calls.length; res = new Result[](length); - for (uint256 i = 0; i < length; i++) { + for (uint256 i; i != length; ++i) { (bool success, bytes memory result) = _delegateToSelf(calls[i].callData, calls[i].allowFailure); res[i] = Result(success, result); } diff --git a/contracts/router/ActionStorageV4.sol b/contracts/router/ActionStorageV4.sol index 2c575878..9db51243 100644 --- a/contracts/router/ActionStorageV4.sol +++ b/contracts/router/ActionStorageV4.sol @@ -21,9 +21,11 @@ contract ActionStorageV4 is RouterStorage, IPActionStorageV4 { function setSelectorToFacets(SelectorsToFacet[] calldata arr) external onlyOwner { CoreStorage storage $ = _getCoreStorage(); - for (uint256 i = 0; i < arr.length; i++) { + uint256 length = arr.length; + for (uint256 i; i != length; ++i) { SelectorsToFacet memory s = arr[i]; - for (uint256 j = 0; j < s.selectors.length; j++) { + uint256 selectorsLength = s.selectors.length; + for (uint256 j; j != selectorsLength; ++j) { $.selectorToFacet[s.selectors[j]] = s.facet; emit SelectorToFacetSet(s.selectors[j], s.facet); } diff --git a/contracts/router/swap-aggregator/kyberswap/l1-contracts/InputScalingHelper.sol b/contracts/router/swap-aggregator/kyberswap/l1-contracts/InputScalingHelper.sol index 4bd27744..e8e82968 100644 --- a/contracts/router/swap-aggregator/kyberswap/l1-contracts/InputScalingHelper.sol +++ b/contracts/router/swap-aggregator/kyberswap/l1-contracts/InputScalingHelper.sol @@ -124,7 +124,7 @@ library InputScalingHelper { desc.amount = newAmount; uint256 nReceivers = desc.srcReceivers.length; - for (uint256 i = 0; i < nReceivers; ) { + for (uint256 i; i != nReceivers; ) { desc.srcAmounts[i] = (desc.srcAmounts[i] * newAmount) / oldAmount; unchecked { ++i; @@ -142,7 +142,7 @@ library InputScalingHelper { SimpleSwapData memory swapData = abi.decode(data, (SimpleSwapData)); uint256 nPools = swapData.firstPools.length; - for (uint256 i = 0; i < nPools; ) { + for (uint256 i; i != nPools; ) { swapData.firstSwapAmounts[i] = (swapData.firstSwapAmounts[i] * newAmount) / oldAmount; unchecked { ++i; @@ -170,7 +170,7 @@ library InputScalingHelper { ); uint256 nSequences = executorDesc.swapSequences.length; - for (uint256 i = 0; i < nSequences; ) { + for (uint256 i; i != nSequences; ) { Swap memory swap = executorDesc.swapSequences[i][0]; bytes4 functionSelector = bytes4(swap.selectorAndFlags); diff --git a/contracts/router/swap-aggregator/kyberswap/l2-contracts/CalldataReader.sol b/contracts/router/swap-aggregator/kyberswap/l2-contracts/CalldataReader.sol index f49474d9..6564cff4 100644 --- a/contracts/router/swap-aggregator/kyberswap/l2-contracts/CalldataReader.sol +++ b/contracts/router/swap-aggregator/kyberswap/l2-contracts/CalldataReader.sol @@ -116,7 +116,7 @@ library CalldataReader { (ret, startByte) = _calldataVal(data, startByte, 1); uint256 length = uint256(uint8(bytes1(ret))); bytesArray = new bytes[](length); - for (uint8 i = 0; i < length; ++i) { + for (uint8 i; i != length; ++i) { (bytesArray[i], startByte) = _readBytes(data, startByte); } return (bytesArray, startByte); @@ -131,7 +131,7 @@ library CalldataReader { (ret, startByte) = _calldataVal(data, startByte, 1); uint256 length = uint256(uint8(bytes1(ret))); addrs = new address[](length); - for (uint8 i = 0; i < length; ++i) { + for (uint8 i; i != length; ++i) { (addrs[i], startByte) = _readAddress(data, startByte); } return (addrs, startByte); @@ -147,7 +147,7 @@ library CalldataReader { (ret, startByte) = _calldataVal(data, startByte, 1); uint256 length = uint256(uint8(bytes1(ret))); uint256[] memory us = new uint256[](length); - for (uint8 i = 0; i < length; ++i) { + for (uint8 i; i != length; ++i) { (us[i], startByte) = _readUint128AsUint256(data, startByte); } return (us, startByte); diff --git a/contracts/router/swap-aggregator/kyberswap/l2-contracts/CalldataWriter.sol b/contracts/router/swap-aggregator/kyberswap/l2-contracts/CalldataWriter.sol index 605c31dd..8dae369d 100644 --- a/contracts/router/swap-aggregator/kyberswap/l2-contracts/CalldataWriter.sol +++ b/contracts/router/swap-aggregator/kyberswap/l2-contracts/CalldataWriter.sol @@ -25,7 +25,7 @@ library CalldataWriter { // write Swap array uint8 lX = uint8(desc.swapSequences.length); shortData = bytes.concat(shortData, bytes1(lX)); - for (uint8 i = 0; i < lX; ++i) { + for (uint8 i; i != lX; ++i) { uint8 lY = uint8(desc.swapSequences[i].length); shortData = bytes.concat(shortData, bytes1(lY)); for (uint8 j = 0; j < lY; ++j) { @@ -46,7 +46,7 @@ library CalldataWriter { address tokenIn ) internal pure returns (bytes[] memory shortData) { uint8 len = uint8(swapDatas.length); - for (uint8 i = 0; i < len; ++i) { + for (uint8 i; i != len; ++i) { swapDatas[i] = _writeSwapSingleSequence(swapDatas[i], tokenIn); } return (swapDatas); @@ -60,7 +60,7 @@ library CalldataWriter { uint8 len = uint8(swaps.length); shortData = bytes.concat(shortData, bytes1(len)); - for (uint8 i = 0; i < len; ++i) { + for (uint8 i; i != len; ++i) { shortData = bytes.concat(shortData, _writeSwap(swaps[i])); } shortData = bytes.concat(shortData, bytes20(tokenIn)); @@ -69,7 +69,7 @@ library CalldataWriter { function _writeAddressArray(address[] memory addrs) internal pure returns (bytes memory data) { uint8 length = uint8(addrs.length); data = bytes.concat(data, bytes1(length)); - for (uint8 i = 0; i < length; ++i) { + for (uint8 i; i != length; ++i) { data = bytes.concat(data, bytes20(addrs[i])); } return data; @@ -78,7 +78,7 @@ library CalldataWriter { function _writeUint256ArrayAsUint128Array(uint256[] memory us) internal pure returns (bytes memory data) { uint8 length = uint8(us.length); data = bytes.concat(data, bytes1(length)); - for (uint8 i = 0; i < length; ++i) { + for (uint8 i; i != length; ++i) { data = bytes.concat(data, bytes16(uint128(us[i]))); } return data; @@ -94,7 +94,7 @@ library CalldataWriter { function _writeBytesArray(bytes[] memory bytesArray) internal pure returns (bytes memory data) { uint8 x = uint8(bytesArray.length); data = bytes.concat(data, bytes1(x)); - for (uint8 i; i < x; ++i) { + for (uint8 i; i != x; ++i) { uint32 length = uint32(bytesArray[i].length); data = bytes.concat(data, bytes4(length)); data = bytes.concat(data, bytesArray[i]); @@ -105,7 +105,7 @@ library CalldataWriter { function _writeBytes32Array(bytes32[] memory bytesArray) internal pure returns (bytes memory data) { uint8 x = uint8(bytesArray.length); data = bytes.concat(data, bytes1(x)); - for (uint8 i; i < x; ++i) { + for (uint8 i; i != x; ++i) { data = bytes.concat(data, bytesArray[i]); } return data; diff --git a/contracts/router/swap-aggregator/kyberswap/l2-contracts/Common.sol b/contracts/router/swap-aggregator/kyberswap/l2-contracts/Common.sol index d9f78239..e4209825 100644 --- a/contracts/router/swap-aggregator/kyberswap/l2-contracts/Common.sol +++ b/contracts/router/swap-aggregator/kyberswap/l2-contracts/Common.sol @@ -34,7 +34,7 @@ library Common { (ret, startByte) = data._calldataVal(startByte, 1); uint256 length = uint256(uint8(bytes1(ret))); bytesArray = new bytes32[](length); - for (uint8 i = 0; i < length; ++i) { + for (uint8 i; i != length; ++i) { (bytesArray[i], startByte) = data._readBytes32(startByte); } return (bytesArray, startByte); diff --git a/contracts/router/swap-aggregator/kyberswap/l2-contracts/ExecutorReader.sol b/contracts/router/swap-aggregator/kyberswap/l2-contracts/ExecutorReader.sol index c8be8bb7..25da591c 100644 --- a/contracts/router/swap-aggregator/kyberswap/l2-contracts/ExecutorReader.sol +++ b/contracts/router/swap-aggregator/kyberswap/l2-contracts/ExecutorReader.sol @@ -15,7 +15,7 @@ library ExecutorReader { (ret, startByte) = CalldataReader._calldataVal(data, startByte, 1); uint256 lX = uint256(uint8(bytes1(ret))); desc.swapSequences = new IAggregationExecutorOptimistic.Swap[][](lX); - for (uint8 i = 0; i < lX; ++i) { + for (uint8 i; i != lX; ++i) { (ret, startByte) = CalldataReader._calldataVal(data, startByte, 1); uint256 lY = uint256(uint8(bytes1(ret))); desc.swapSequences[i] = new IAggregationExecutorOptimistic.Swap[](lY); @@ -42,7 +42,7 @@ library ExecutorReader { (ret, startByte) = CalldataReader._calldataVal(data, startByte, 1); uint256 len = uint256(uint8(bytes1(ret))); swaps = new IAggregationExecutorOptimistic.Swap[](len); - for (uint8 i = 0; i < len; ++i) { + for (uint8 i; i != len; ++i) { (swaps[i], startByte) = _readSwap(data, startByte); } (tokenIn, startByte) = CalldataReader._readAddress(data, startByte); diff --git a/contracts/router/swap-aggregator/kyberswap/l2-contracts/InputScalingHelperL2.sol b/contracts/router/swap-aggregator/kyberswap/l2-contracts/InputScalingHelperL2.sol index 55585f91..f27936af 100644 --- a/contracts/router/swap-aggregator/kyberswap/l2-contracts/InputScalingHelperL2.sol +++ b/contracts/router/swap-aggregator/kyberswap/l2-contracts/InputScalingHelperL2.sol @@ -144,7 +144,7 @@ library InputScalingHelperL2 { desc.amount = (desc.amount * newAmount) / oldAmount; uint256 nReceivers = desc.srcReceivers.length; - for (uint256 i = 0; i < nReceivers; ) { + for (uint256 i; i != nReceivers; ) { desc.srcAmounts[i] = (desc.srcAmounts[i] * newAmount) / oldAmount; unchecked { ++i; @@ -166,7 +166,7 @@ library InputScalingHelperL2 { uint256 nPools = simpleSwapData.firstPools.length; address tokenIn; - for (uint256 i = 0; i < nPools; ) { + for (uint256 i; i != nPools; ) { simpleSwapData.firstSwapAmounts[i] = (simpleSwapData.firstSwapAmounts[i] * newAmount) / oldAmount; IExecutorHelperL2.Swap[] memory dexData; @@ -212,7 +212,7 @@ library InputScalingHelperL2 { ); uint256 nSequences = executorDesc.swapSequences.length; - for (uint256 i = 0; i < nSequences; ) { + for (uint256 i; i != nSequences; ) { // only need to scale the first dex in each sequence IExecutorHelperL2.Swap memory swap = executorDesc.swapSequences[i][0]; executorDesc.swapSequences[i][0] = _scaleDexData(swap, oldAmount, newAmount);