Omniscia Boson Protocol Audit

BundleBase Code Style Findings

BundleBase Code Style Findings

BBS-01C: Repetitive Invocations of Getter Function

TypeSeverityLocation
Gas OptimizationBundleBase.sol:L45, L48, L69, L84

Description:

The linked statements repetitively invoke the same getter function whilst its return value remains unchanged.

Example:

contracts/protocol/bases/BundleBase.sol
55for (uint256 i = 0; i < _bundle.offerIds.length; i++) {
56 uint256 offerId = _bundle.offerIds[i];
57
58 // Calculate bundle offers total quantity available.
59 offersTotalQuantityAvailable = calculateOffersTotalQuantity(offersTotalQuantityAvailable, offerId);
60
61 (bool bundleByOfferExists, ) = fetchBundleIdByOffer(offerId);
62 require(!bundleByOfferExists, BUNDLE_OFFER_MUST_BE_UNIQUE);
63
64 (bool exchangeIdsForOfferExists, ) = getExchangeIdsByOffer(offerId);
65 // make sure exchange does not already exist for this offer id.
66 require(!exchangeIdsForOfferExists, EXCHANGE_FOR_OFFER_EXISTS);
67
68 // Add to bundleIdByOffer mapping
69 protocolLookups().bundleIdByOffer[offerId] = bundleId;
70}
71
72for (uint256 i = 0; i < _bundle.twinIds.length; i++) {
73 uint256 twinId = _bundle.twinIds[i];
74
75 // A twin can't belong to multiple bundles
76 (bool bundleForTwinExist, ) = fetchBundleIdByTwin(twinId);
77 require(!bundleForTwinExist, BUNDLE_TWIN_MUST_BE_UNIQUE);
78
79 if (_bundle.offerIds.length > 0) {
80 bundleSupplyChecks(offersTotalQuantityAvailable, twinId);
81 }
82
83 // Push to bundleIdsByTwin mapping
84 protocolLookups().bundleIdByTwin[_bundle.twinIds[i]] = bundleId;
85}

Recommendation:

We advise the getter function to be invoked once and its result to be stored to a local variable that is consequently utilized optimizing the gas cost of the statements significantly.

Alleviation (44009967e4f68092941d841e9e0f5dd2bb31bf0b):

The protocol limits and lookups are now correctly cached to local variable declarations thus optimizing the codebase's gas cost.