// Ensure fraction can be applied to the value with no remainder. Note
// that the denominator cannot be zero.
bool exact;
assembly {
// Ensure new value contains no remainder via mulmod operator.
// Credit to @hrkrshnn + @axic for proposing this optimal solution.
exact := iszero(mulmod(value, numerator, denominator))
}
// Ensure that division gave a final result with no remainder.
if (!exact) {
revert InexactFraction();
}
Where InexactFraction_error_signature and InexactFraction_error_len is precomputed and stored as constant based on revert InexactFraction();
This reduce gas on storing exact flag and duplicated if (!exact) check
_applyFulfillment in FulfillmentApplier can set execution.item.recipient = payable(execution.offerer); if execution.item.amount == 0 to reduce gas on processing zero amount execution
// Set the offerer as the receipient if execution amount is zero.
if (execution.item.amount == 0) {
execution.item.recipient = payable(execution.offerer);
}
Before returning into
// Reuse execution struct with consideration amount and recipient.
execution.item.amount = considerationItem.amount;
execution.item.recipient = considerationItem.recipient;
// Return the final execution that will be triggered for relevant items.
return execution; // Execution(considerationItem, offerer, conduitKey);
which result in
// Reuse execution struct with consideration amount and recipient.
execution.item.amount = considerationItem.amount;
execution.item.recipient = considerationItem.recipient;
// Set the offerer as the receipient if execution amount is zero.
if (execution.item.amount == 0) {
execution.item.recipient = payable(execution.offerer);
}
// Return the final execution that will be triggered for relevant items.
return execution; // Execution(considerationItem, offerer, conduitKey);
To let execution with zero amount being skipped in _executeAvailableFulfillments function in OrderCombiner
// Derive aggregated execution corresponding with fulfillment.
Execution memory execution = _aggregateAvailable(
advancedOrders,
Side.OFFER,
components,
fulfillerConduitKey
);
// If offerer and recipient on the execution are the same...
if (execution.item.recipient == execution.offerer) {
// increment total filtered executions.
totalFilteredExecutions += 1;
} else {
// Otherwise, assign the execution to the executions array.
executions[i - totalFilteredExecutions] = execution;
}
Which lead to following optimization path:
execution.item.amount == 0
execution.item.recipient == execution.offerer
totalFilteredExecutions += 1 (skipping) instead of inserting into executions list
Execution skipped
Save a lot of gas on any function that used to execute that execution
Total: 2 topics
Remainder check in _getFraction in AmountDeriver can be simplified to if iszero... revert
https://github.com/code-423n4/2022-05-opensea-seaport/blob/4140473b1f85d0df602548ad260b1739ddd734a5/contracts/lib/AmountDeriver.sol#L101-L111
Can be simplified into
Where
InexactFraction_error_signature
andInexactFraction_error_len
is precomputed and stored as constant based onrevert InexactFraction();
This reduce gas on storing
exact
flag and duplicatedif (!exact)
check_applyFulfillment in FulfillmentApplier can set execution.item.recipient = payable(execution.offerer); if execution.item.amount == 0 to reduce gas on processing zero amount execution
https://github.com/code-423n4/2022-05-opensea-seaport/blob/4140473b1f85d0df602548ad260b1739ddd734a5/contracts/lib/FulfillmentApplier.sol#L115-L120
We can add
Before returning into
which result in
To let execution with zero amount being skipped in _executeAvailableFulfillments function in OrderCombiner
https://github.com/code-423n4/2022-05-opensea-seaport/blob/4140473b1f85d0df602548ad260b1739ddd734a5/contracts/lib/OrderCombiner.sol#L479-L494
https://github.com/code-423n4/2022-05-opensea-seaport/blob/4140473b1f85d0df602548ad260b1739ddd734a5/contracts/lib/OrderCombiner.sol#L504-L521
Which lead to following optimization path: