OpenSea Seaport contest - oyc_109's results

A marketplace contract for safely and efficiently creating and fulfilling orders for ERC721 and ERC1155 items.

General Information

Platform: Code4rena

Start Date: 20/05/2022

Pot Size: $1,000,000 USDC

Total HM: 4

Participants: 59

Period: 14 days

Judge: leastwood

Id: 128

League: ETH

OpenSea

Findings Distribution

Researcher Performance

Rank: 24/59

Findings: 2

Award: $2,341.16

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Awards

1904.8298 USDC - $1,904.83

Labels

bug
QA (Quality Assurance)

External Links

missing checks for zero address

description

Checking addresses against zero-address during initialization or during setting is a security best-practice. However, such checks are missing in the createConduit() function in ConduitController.sol

/2022-05-opensea-seaport/contracts/conduit/ConduitController.sol 94: _conduits[conduit].owner = initialOwner;

This is not consistant with the transferOwnership() function where it does check for address(0)

/2022-05-opensea-seaport/contracts/conduit/ConduitController.sol 196: // Ensure the new potential owner is not an invalid address. 197: if (newPotentialOwner == address(0)) { 198: revert NewPotentialOwnerIsZeroAddress(conduit); 199: }

Impact: Allowing zero-addresses may lead to contract redeployments since createConduit() can only be called once.

Unspecific Compiler Version Pragma

description

Avoid floating pragmas for non-library contracts.

While floating pragmas make sense for libraries to allow them to be included with multiple different versions of applications, it may be a security risk for application implementations.

A known vulnerable compiler version may accidentally be selected or security tools might fall-back to an older compiler version ending up checking a different EVM compilation that is ultimately deployed on the blockchain.

It is recommended to pin to a concrete compiler version.

findings

/2022-05-opensea-seaport/contracts/conduit/Conduit.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/conduit/ConduitController.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/AbridgedTokenInterfaces.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/AmountDerivationErrors.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/ConduitControllerInterface.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/ConduitInterface.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/ConsiderationEventsAndErrors.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/ConsiderationInterface.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/CriteriaResolutionErrors.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/EIP1271Interface.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/FulfillmentApplicationErrors.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/ImmutableCreate2FactoryInterface.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/ReentrancyErrors.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/SeaportInterface.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/SignatureVerificationErrors.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/TokenTransferrerErrors.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/ZoneInteractionErrors.sol 2: pragma solidity >=0.8.7; /2022-05-opensea-seaport/contracts/interfaces/ZoneInterface.sol 2: pragma solidity >=0.8.7;

#0 - GalloDaSballo

2022-07-17T18:23:48Z

missing checks for zero address

Valid Low per #56

#1 - GalloDaSballo

2022-07-19T22:15:39Z

1 NC as well

1L 1NC

named returns and a return statement isn’t necessary

description

Removing unused named returns variables can reduce gas usage (MSTOREs/MLOADs) and improve code clarity. To save gas and improve code quality: consider using only one of those.

findings

/2022-05-opensea-seaport/contracts/lib/FulfillmentApplier.sol 48: function _applyFulfillment( 49: AdvancedOrder[] memory advancedOrders, 50: FulfillmentComponent[] calldata offerComponents, 51: FulfillmentComponent[] calldata considerationComponents 52: ) internal view returns (Execution memory execution) { ... 120: return execution; // Execution(considerationItem, offerer, conduitKey);
/2022-05-opensea-seaport/contracts/lib/OrderCombiner.sol 107: function _fulfillAvailableAdvancedOrders( 108: AdvancedOrder[] memory advancedOrders, 109: CriteriaResolver[] memory criteriaResolvers, 110: FulfillmentComponent[][] calldata offerFulfillments, 111: FulfillmentComponent[][] calldata considerationFulfillments, 112: bytes32 fulfillerConduitKey, 113: uint256 maximumFulfilled 114: ) 115: internal 116: returns (bool[] memory availableOrders, Execution[] memory executions) 117: { ... 135: return (availableOrders, executions);
/2022-05-opensea-seaport/contracts/lib/OrderFulfiller.sol 457: function _convertOrdersToAdvanced(Order[] calldata orders) 458: internal 459: pure 460: returns (AdvancedOrder[] memory advancedOrders) ... 478: return advancedOrders;
/2022-05-opensea-seaport/contracts/lib/OrderValidator.sol 104: function _validateOrderAndUpdateStatus( 105: AdvancedOrder memory advancedOrder, 106: CriteriaResolver[] memory criteriaResolvers, 107: bool revertOnInvalid, 108: bytes32[] memory priorOrderHashes 109: ) 110: internal 111: returns ( 112: bytes32 orderHash, 113: uint256 newNumerator, 114: uint256 newDenominator 115: ) 116: { ... /2022-05-opensea-seaport/contracts/lib/OrderValidator.sol 242: return (orderHash, numerator, denominator);
/2022-05-opensea-seaport/contracts/lib/Verifiers.sol 37: function _verifyTime( 38: uint256 startTime, 39: uint256 endTime, 40: bool revertOnInvalid 41: ) internal view returns (bool valid) { ... 50: return false;
/2022-05-opensea-seaport/contracts/lib/Verifiers.sol 102: function _verifyOrderStatus( 103: bytes32 orderHash, 104: OrderStatus memory orderStatus, 105: bool onlyAllowUnused, 106: bool revertOnInvalid 107: ) internal pure returns (bool valid) { ... 116: return false; 133: return false;

do not calculate constants

description

Due to how constant variables are implemented (replacements at compile-time), an expression assigned to a constant variable is recomputed each time that the variable is used, which wastes some gas.

recommend hard coding constants to save gas

findings

/2022-05-opensea-seaport/contracts/lib/ConsiderationConstants.sol 235: uint256 constant BasicOrder_offerItem_typeHash_ptr = DefaultFreeMemoryPointer;
/2022-05-opensea-seaport/contracts/lib/TokenTransferrerConstants.sol 81: bytes4 constant ERC1155_safeBatchTransferFrom_selector = bytes4( 82: bytes32(ERC1155_safeBatchTransferFrom_signature) 83: ); 85: uint256 constant ERC721_transferFrom_signature = ERC20_transferFrom_signature;

do not cache variable used only once

description

for variables only used once, changing it to inline saves gas

findings

/2022-05-opensea-seaport/contracts/conduit/ConduitController.sol 425: uint256 totalChannels = _conduits[conduit].channels.length;
/2022-05-opensea-seaport/contracts/lib/AmountDeriver.sol 56: uint256 totalBeforeDivision = ( 114: uint256 valueTimesNumerator = value * numerator;

Don't Initialize Variables with Default Value

description

Uninitialized variables are assigned with the types default value.

Explicitly initializing a variable with it's default value costs unnecesary gas.

findings

/2022-05-opensea-seaport/contracts/conduit/Conduit.sol 66: for (uint256 i = 0; i < totalStandardTransfers; ) { //@audit dont initialize i 130: for (uint256 i = 0; i < totalStandardTransfers; ) {
/2022-05-opensea-seaport/contracts/lib/AmountDeriver.sol 44: uint256 extraCeiling = 0;
/2022-05-opensea-seaport/contracts/lib/BasicOrderFulfiller.sol 948: for (uint256 i = 0; i < totalAdditionalRecipients; ) { 1040: for (uint256 i = 0; i < totalAdditionalRecipients; ) {
/2022-05-opensea-seaport/contracts/lib/CriteriaResolution.sol 56: for (uint256 i = 0; i < totalCriteriaResolvers; ++i) { 166: for (uint256 i = 0; i < totalAdvancedOrders; ++i) { 184: for (uint256 j = 0; j < totalItems; ++j) { //@audit dont initialize j 199: for (uint256 j = 0; j < totalItems; ++j) {
/2022-05-opensea-seaport/contracts/lib/OrderCombiner.sol 181: for (uint256 i = 0; i < totalOrders; ++i) { 247: for (uint256 j = 0; j < offer.length; ++j) { 291: for (uint256 j = 0; j < consideration.length; ++j) { 373: for (uint256 i = 0; i < totalOrders; ++i) {
/2022-05-opensea-seaport/contracts/lib/OrderFulfiller.sol 217: for (uint256 i = 0; i < orderParameters.offer.length; ) { 306: for (uint256 i = 0; i < orderParameters.consideration.length; ) {
/2022-05-opensea-seaport/contracts/lib/OrderValidator.sol 272: for (uint256 i = 0; i < totalOrders; ) { 350: for (uint256 i = 0; i < totalOrders; ) {

cache in variables instead of loading

description

The code can be optimized by minimising the number of SLOADs. SLOADs are expensive (100 gas) compared to MLOADs/MSTOREs (3 gas).

array lengths should be cached outside of the loop

findings

/2022-05-opensea-seaport/contracts/lib/OrderCombiner.sol 247: for (uint256 j = 0; j < offer.length; ++j) { 291: for (uint256 j = 0; j < consideration.length; ++j) {
/2022-05-opensea-seaport/contracts/lib/OrderFulfiller.sol 217: for (uint256 i = 0; i < orderParameters.offer.length; ) { 306: for (uint256 i = 0; i < orderParameters.consideration.length; ) {

use calldata instead of memory

description

Use calldata instead of memory for function parameters saves gas

use calldata instead of memory if the function argument is only read.

findings

/2022-05-opensea-seaport/contracts/lib/Consideration.sol 301: AdvancedOrder[] memory advancedOrders, 399: AdvancedOrder[] memory advancedOrders,
/2022-05-opensea-seaport/contracts/lib/CriteriaResolution.sol 45: CriteriaResolver[] memory criteriaResolvers 244: bytes32[] memory proof
/2022-05-opensea-seaport/contracts/lib/Executor.sol 55: ReceivedItem memory item,
/2022-05-opensea-seaport/contracts/lib/FulfillmentApplier.sol 142: AdvancedOrder[] memory advancedOrders, 144: FulfillmentComponent[] memory fulfillmentComponents,
/2022-05-opensea-seaport/contracts/lib/OrderCombiner.sol 108: AdvancedOrder[] memory advancedOrders, 109: CriteriaResolver[] memory criteriaResolvers, 159: AdvancedOrder[] memory advancedOrders, 160: CriteriaResolver[] memory criteriaResolvers,
/2022-05-opensea-seaport/contracts/lib/OrderFulfiller.sol 76: AdvancedOrder memory advancedOrder, 77: CriteriaResolver[] memory criteriaResolvers,
/2022-05-opensea-seaport/contracts/lib/OrderFulfiller.sol 400: OfferItem[] memory offer, 401: ConsiderationItem[] memory consideration
/2022-05-opensea-seaport/contracts/lib/OrderValidator.sol 105: AdvancedOrder memory advancedOrder, 106: CriteriaResolver[] memory criteriaResolvers, 108: bytes32[] memory priorOrderHashes
/2022-05-opensea-seaport/contracts/lib/ZoneInteraction.sol 105: AdvancedOrder memory advancedOrder, 106: CriteriaResolver[] memory criteriaResolvers, 107: bytes32[] memory priorOrderHashes,
AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter