Omniscia Boson Protocol Audit

FundsBase Manual Review Findings

FundsBase Manual Review Findings

FBE-01M: Deprecated Approval Function

Description:

The FundsBase::releaseFunds function will issue a SafeERC20::safeApprove function invocation of OpenZeppelin's v4.9.6 release which is officially deprecated.

Impact:

Although unlikely, any approval by the FundsBase::releaseFunds implementation that is not consumed in full can cause fund release revert errors.

Example:

contracts/protocol/bases/FundsBase.sol
275IERC20(exchangeToken).safeApprove(exchange.mutualizerAddress, returnAmount);

Recommendation:

We advise the code to utilize SafeERC20::forceApprove instead, preventing any lingering approvals from causing fatal revert errors.

Alleviation (efd5d1a8f23c3bca7c25273ea4c912a367250119):

The code was updated to set the allowance of the mutualizer via the SafeERC20::forceApprove function, addressing this exhibit.

FBE-02M: Insecure Integration of Dispute Resolution Mutualizer

Description:

The FundsBase::releaseFunds function will interact with the IDRFeeMutualizer regardless of whether an actual refund is meant to be performed as it will notify the DRFeeMutualizer even with an argument of 0 as the _returnedFeeAmount.

A malicious mutualizer can induce a forcible revert, freezing any attempt to release funds for a particular exchange.

Impact:

A malicious mutualizer can induce errors in fund releases for Boson Protocol exchanges.

Example:

contracts/protocol/bases/FundsBase.sol
252// Return unused DR fee to mutualizer or seller's pool
253if (drTerms.feeAmount != 0) {
254 uint256 returnAmount = drTerms.feeAmount - payoff.disputeResolver;
255
256 // Use exchange-level mutualizer address (locked at commitment time)
257 if (exchange.mutualizerAddress == address(0)) {
258 if (returnAmount > 0) {
259 increaseAvailableFundsAndEmitEvent(
260 _exchangeId,
261 offer.sellerId,
262 exchangeToken,
263 returnAmount,
264 sender
265 );
266 }
267 } else {
268 if (exchangeToken == address(0)) {
269 IDRFeeMutualizer(exchange.mutualizerAddress).returnDRFee{ value: returnAmount }(
270 _exchangeId,
271 returnAmount
272 );
273 } else {
274 if (returnAmount > 0) {
275 IERC20(exchangeToken).safeApprove(exchange.mutualizerAddress, returnAmount);
276 }
277 IDRFeeMutualizer(exchange.mutualizerAddress).returnDRFee(_exchangeId, returnAmount);
278 }
279 }

Recommendation:

We advise the code to ensure that the DRFeeMutualizer interaction is performed as securely as possible, ensuring that revert errors are ignored (or logged for a retry), and that a sensible gas stipend is provided to the mutualizerAddress to ensure that a Denial-of-Service attack through gas bombing cannot be attempted.

Alleviation (efd5d1a8f2):

The code was updated by handling a revert in the IDRFeeMutualizer::finalizeExchange call as well as allocating a fixed gas stipend to it.

We consider a non-dynamic gas stipend to be significantly restrictive as mutualizer implementations may change and the EVMs the project is deployed on may change as well, and we advise a dynamically configurable value to be utilized instead.

Alleviation (73585830fd):

The Boson Protocol team introduced functions to administratively configure the gas allocation of fee mutualizer calls, fully alleviating this exhibit.