Omniscia Boson Protocol Audit

FundsLib Code Style Findings

FundsLib Code Style Findings

FLB-01C: Ineffectual Usage of Safe Arithmetics

TypeSeverityLocation
Language SpecificFundsLib.sol:L328

Description:

The linked mathematical operation is guaranteed to be performed safely by surrounding conditionals evaluated in either require checks or if-else constructs.

Example:

contracts/protocol/libs/FundsLib.sol
326// make sure that seller has enough funds in the pool and reduce the available funds
327require(availableFunds >= _amount, INSUFFICIENT_AVAILABLE_FUNDS);
328pl.availableFunds[_entityId][_tokenAddress] = availableFunds - _amount;

Recommendation:

Given that safe arithmetics are toggled on by default in pragma versions of 0.8.X, we advise the linked statement to be wrapped in an unchecked code block thereby optimizing its execution cost.

Alleviation (44009967e4f68092941d841e9e0f5dd2bb31bf0b):

An unchecked code block has been introduced surrounding the linked arithmetic statement thus optimizing its execution cost safely.

FLB-02C: Inefficient mapping Lookups

TypeSeverityLocation
Gas OptimizationFundsLib.sol:L295, L296, L298, L302, L324, L328, L332, L334, L338, L340, L342, L345, L347

Description:

The linked statements perform key-based lookup operations on mapping declarations from storage multiple times for the same key redundantly.

Example:

contracts/protocol/libs/FundsLib.sol
323// get available funds from storage
324uint256 availableFunds = pl.availableFunds[_entityId][_tokenAddress];
325
326// make sure that seller has enough funds in the pool and reduce the available funds
327require(availableFunds >= _amount, INSUFFICIENT_AVAILABLE_FUNDS);
328pl.availableFunds[_entityId][_tokenAddress] = availableFunds - _amount;
329
330// if availableFunds are totally emptied, the token address is removed from the seller's tokenList
331if (availableFunds == _amount) {
332 uint256 lastTokenIndex = pl.tokenList[_entityId].length - 1;
333 //Get the index in the tokenList array, which is 1 less than the tokenIndexByAccount index
334 uint256 index = pl.tokenIndexByAccount[_entityId][_tokenAddress] - 1;
335 if (index != lastTokenIndex) {
336 // if index == len - 1 then only pop and delete are needed
337 // Need to fill gap caused by delete if more than one element in storage array
338 address tokenToMove = pl.tokenList[_entityId][lastTokenIndex];
339 // Copy the last token in the array to this index to fill the gap
340 pl.tokenList[_entityId][index] = tokenToMove;
341 // Reset index mapping. Should be index in tokenList array + 1
342 pl.tokenIndexByAccount[_entityId][tokenToMove] = index + 1;
343 }
344 // Delete last token address in the array, which was just moved to fill the gap
345 pl.tokenList[_entityId].pop();
346 //Delete from index mapping
347 delete pl.tokenIndexByAccount[_entityId][_tokenAddress];
348}

Recommendation:

As the lookups internally perform an expensive keccak256 operation, we advise the lookups to be cached wherever possible to a single local declaration that either holds the value of the mapping in case of primitive types or holds a storage pointer to the struct contained.

Alleviation (44009967e4f68092941d841e9e0f5dd2bb31bf0b):

The referenced mapping lookups have been optimized to the greatest extent possible thus greatly reducing the gas cost of the codebase.

FLB-03C: Inexplicable Contract Specifier

TypeSeverityLocation
Code StyleFundsLib.sol:L261

Description:

The decreaseAvailableFunds function is invoked using the contract specifier FundsLib which is the contract itself.

Example:

contracts/protocol/libs/FundsLib.sol
261FundsLib.decreaseAvailableFunds(_entityId, _tokenAddress, _amount);

Recommendation:

We advise the contract specifier to be omitted as decreaseAvailableFunds will refer to the function defined within the contract in this case.

Alleviation (44009967e4f68092941d841e9e0f5dd2bb31bf0b):

The FundsLib specifier has been removed from the referenced function invocation optimizing the code's legibility.