code-423n4 / 2022-05-opensea-seaport-findings

1 stars 0 forks source link

Gas Optimizations #107

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

For-Loops: Increments can be unchecked

In Solidity 0.8+, there’s a default overflow check on unsigned integers. It’s possible to uncheck this in for-loops and save some gas at each iteration, but at the cost of some code readability, as this uncheck cannot be made inline.

The code would go from:

for (uint256 i; i < numIterations; i++) {   // ...  }

to:

for (uint256 i; i < numIterations;) {   // ...   unchecked { ++i; }  }

Instances:

reference/conduit/ReferenceConduit.sol:48: for (uint256 i = 0; i < totalStandardTransfers; i++) { reference/conduit/ReferenceConduit.sol:69: for (uint256 i = 0; i < totalBatchTransfers; i++) { reference/conduit/ReferenceConduit.sol:91: for (uint256 i = 0; i < totalStandardTransfers; i++) { reference/conduit/ReferenceConduit.sol:102: for (uint256 i = 0; i < totalBatchTransfers; i++) { test/foundry/utils/StructCopier.sol:16: for (uint256 i = 0; i < _offerItems.length; i++) { test/foundry/utils/StructCopier.sol:37: for (uint256 i = 0; i < _offerItems.length; i++) { test/foundry/utils/StructCopier.sol:103: for (uint256 i = 0; i < src.length; i++) { test/foundry/utils/StructCopier.sol:114: for (uint256 i = 0; i < src.length; i++) { test/foundry/utils/StructCopier.sol:161: for (uint256 i = 0; i < src.length; i++) { test/foundry/utils/StructCopier.sol:174: for (uint256 i = 0; i < src.length; i++) { test/foundry/utils/StructCopier.sol:186: for (uint256 i = 0; i < src.length; i++) { test/foundry/utils/StructCopier.sol:198: for (uint256 i = 0; i < src.length; i++) { test/foundry/utils/StructCopier.sol:210: for (uint256 i = 0; i < src.length; i++) { test/foundry/utils/StructCopier.sol:222: for (uint256 i = 0; i < src.length; i++) { test/foundry/utils/BaseOrderTest.sol:142: for (uint256 i; i < _values.length; i++) { test/foundry/utils/BaseOrderTest.sol:153: for (uint256 i; i < _values.length; i++) { test/foundry/utils/BaseOrderTest.sol:443: for (uint256 i = 0; i < _offerItems.length; i++) { test/foundry/utils/BaseOrderTest.sol:464: for (uint256 i = 0; i < _offerItems.length; i++) { test/foundry/utils/BaseOrderTest.sol:511: for (uint256 i = 0; i < erc20s.length; i++) { test/foundry/utils/BaseOrderTest.sol:520: for (uint256 i = 0; i < erc20s.length; i++) { test/foundry/utils/BaseOrderTest.sol:526: for (uint256 i = 0; i < erc721s.length; i++) { test/foundry/utils/BaseOrderTest.sol:532: for (uint256 i = 0; i < erc1155s.length; i++) { test/foundry/utils/BaseOrderTest.sol:555: for (uint256 i = 0; i < considerationItems.length; i++) { test/foundry/utils/BaseOrderTest.sol:598: for (uint256 i = 0; i < accounts.length; i++) { test/foundry/utils/BaseOrderTest.sol:604: for (uint256 i = 0; i < allTokens.length; i++) { test/foundry/utils/BaseOrderTest.sol:613: for (uint256 i = 0; i < accounts.length; i++) { test/foundry/utils/BaseOrderTest.sol:622: for (uint256 i = 0; i < erc20s.length; i++) { test/foundry/utils/BaseConsiderationTest.sol:233: for (uint256 i = 0; i < writeSlots.length; i++) { test/foundry/FulfillAvailableAdvancedOrder.t.sol:33: for (uint256 i; i < 4; i++) { test/foundry/FullfillAvailableOrder.t.sol:30: for (uint256 i; i < 4; i++) { test/foundry/FullfillAvailableOrder.t.sol:47: for (uint256 i; i < 4; i++) { test/foundry/MatchOrders.t.sol:60: for (uint256 i = 1; i < 4; i++) { test/foundry/MatchOrders.t.sol:75: for (uint256 i = 1; i < 4; i++) { test/foundry/conduit/BaseConduitTest.sol:142: for (uint256 i = 0; i < truncatedNumTokenIds; i++) { test/foundry/conduit/BaseConduitTest.sol:173: for (uint256 i = 0; i < original.length; i++) { test/foundry/conduit/BaseConduitTest.sol:176: for (uint256 i = 0; i < extension.length; i++) { test/foundry/conduit/BaseConduitTest.sol:190: for (uint256 i = 0; i < original.length; i++) { test/foundry/conduit/BaseConduitTest.sol:193: for (uint256 i = 0; i < extension.length; i++) { test/foundry/conduit/BaseConduitTest.sol:240: for (uint256 n = 0; n < batchIntermediate.idAmounts.length; n++) { test/foundry/conduit/BaseConduitTest.sol:264: for (uint256 i; i < transfers.length; i++) { test/foundry/conduit/BaseConduitTest.sol:276: for (uint256 i; i < batchTransfers.length; i++) { test/foundry/conduit/BaseConduitTest.sol:293: for (uint256 i = 0; i < transfers.length; i++) { test/foundry/conduit/BaseConduitTest.sol:321: for (uint256 i = 0; i < batchTransfers.length; i++) { test/foundry/conduit/BaseConduitTest.sol:326: for (uint256 n = 0; n < batchTransfer.ids.length; n++) { test/foundry/conduit/BaseConduitTest.sol:355: for (uint256 i = 0; i < batchTransfer.ids.length; i++) { test/foundry/conduit/BaseConduitTest.sol:366: for (uint256 i = 0; i < transfers.length; i++) { test/foundry/conduit/BaseConduitTest.sol:378: for (uint256 i = 0; i < batchTransfers.length; i++) { test/foundry/conduit/BaseConduitTest.sol:392: for (uint256 i = 0; i < batchTransfer.ids.length; i++) { test/foundry/conduit/BaseConduitTest.sol:403: for (uint256 i = 0; i < transfers.length; i++) { test/foundry/conduit/BaseConduitTest.sol:412: for (uint256 i = 0; i < batchTransfers.length; i++) { test/foundry/conduit/BaseConduitTest.sol:422: for (uint256 i = 0; i < transfers.length; i++) { test/foundry/conduit/BaseConduitTest.sol:426: for (uint256 i = 0; i < batchTransfers.length; i++) { test/foundry/conduit/ConduitExecuteWithBatch1155.t.sol:29: for (uint8 i = 0; i < inputs.transferIntermediates.length; i++) { test/foundry/conduit/ConduitExecuteWithBatch1155.t.sol:40: for (uint8 j = 0; j < inputs.batchIntermediates.length; j++) { test/foundry/conduit/ConduitExecuteWithBatch1155.t.sol:84: for (uint256 i = 0; i < context.transfers.length; i++) { test/foundry/conduit/ConduitExecuteWithBatch1155.t.sol:110: for (uint256 i = 0; i < context.batchTransfers.length; i++) { test/foundry/conduit/ConduitExecuteWithBatch1155.t.sol:117: for (uint256 j = 0; j < batchTransfer.ids.length; j++) { test/foundry/conduit/ConduitExecuteWithBatch1155.t.sol:131: for (uint256 j = 0; j < actualBatchBalances.length; j++) { test/foundry/conduit/ConduitExecute.t.sol:26: for (uint8 i; i < inputs.intermediates.length; i++) { test/foundry/conduit/ConduitExecute.t.sol:50: for (uint256 i; i < context.transfers.length; i++) { test/foundry/conduit/ConduitExecuteBatch1155.t.sol:27: for (uint8 j = 0; j < inputs.batchIntermediates.length; j++) { test/foundry/conduit/ConduitExecuteBatch1155.t.sol:58: for (uint256 i = 0; i < context.batchTransfers.length; i++) { test/foundry/conduit/ConduitExecuteBatch1155.t.sol:65: for (uint256 j = 0; j < batchTransfer.ids.length; j++) { test/foundry/conduit/ConduitExecuteBatch1155.t.sol:79: for (uint256 j = 0; j < actualBatchBalances.length; j++) { test/foundry/FulfillOrderTest.sol:837: for (uint128 i = 1; i < context.numTips + 1; i++) { test/foundry/FulfillOrderTest.sol:966: for (uint128 i = 1; i < context.numTips + 1; i++) { test/foundry/FulfillOrderTest.sol:1087: for (uint128 i = 1; i < context.numTips + 1; i++) { test/foundry/FulfillOrderTest.sol:1209: for (uint128 i = 1; i < context.numTips + 1; i++) { test/foundry/FulfillOrderTest.sol:1329: for (uint256 i = 1; i < context.numTips + uint256(1); i++) { test/foundry/FulfillOrderTest.sol:1452: for (uint256 i = 1; i < context.numTips + uint256(1); i++) { test/foundry/FulfillOrderTest.sol:1571: for (uint256 i = 1; i < context.numTips + uint256(1); i++) { test/foundry/FulfillOrderTest.sol:1692: for (uint256 i = 1; i < context.numTips + uint256(1); i++) { test/foundry/MatchAdvancedOrder.t.sol:35: for (uint256 i = 1; i < 4; i++) { test/foundry/MatchAdvancedOrder.t.sol:53: for (uint256 i = 1; i < 4; i++) { test/foundry/NonReentrant.t.sol:71: for (uint256 i; i < 7; i++) { test/foundry/NonReentrant.t.sol:72: for (uint256 j; j < 10; j++) {

HardlyDifficult commented 2 years ago

Grouping with https://github.com/code-423n4/2022-05-opensea-seaport-findings/issues/59

HardlyDifficult commented 2 years ago

Warden submitted multiple Gas Optimizations. Will not be judged.