Omniscia Myso Finance Audit

BorrowerGateway Code Style Findings

BorrowerGateway Code Style Findings

BGY-01C: Code Simplification

TypeSeverityLocation
Gas OptimizationBorrowerGateway.sol:L286-L329

Description:

The referenced code block can be simplified as both branches of the upper-most if-else clause perform the same actions albeit with different arguments (LenderVaultImpl::transferCollFromCompartment and LenderVaultImpl::transferTo).

Example:

contracts/peer-to-peer/BorrowerGateway.sol
286if (callbackAddr == address(0)) {
287 if (loan.collTokenCompartmentAddr != address(0)) {
288 ILenderVaultImpl(lenderVault).transferCollFromCompartment(
289 loanRepayInstructions.targetRepayAmount,
290 loan.initRepayAmount - loan.amountRepaidSoFar,
291 loan.borrower,
292 loan.collToken,
293 callbackAddr,
294 loan.collTokenCompartmentAddr
295 );
296 } else {
297 ILenderVaultImpl(lenderVault).transferTo(
298 loan.collToken,
299 loan.borrower,
300 reclaimCollAmount
301 );
302 }
303} else {
304 if (
305 IAddressRegistry(addressRegistry).whitelistState(
306 callbackAddr
307 ) != DataTypesPeerToPeer.WhitelistState.CALLBACK
308 ) {
309 revert Errors.NonWhitelistedCallback();
310 }
311 if (loan.collTokenCompartmentAddr != address(0)) {
312 ILenderVaultImpl(lenderVault).transferCollFromCompartment(
313 loanRepayInstructions.targetRepayAmount,
314 loan.initRepayAmount - loan.amountRepaidSoFar,
315 loan.borrower,
316 loan.collToken,
317 callbackAddr,
318 loan.collTokenCompartmentAddr
319 );
320 IVaultCallback(callbackAddr).repayCallback(loan, callbackData);
321 } else {
322 ILenderVaultImpl(lenderVault).transferTo(
323 loan.collToken,
324 callbackAddr,
325 reclaimCollAmount
326 );
327 IVaultCallback(callbackAddr).repayCallback(loan, callbackData);
328 }
329}

Recommendation:

We advise the uppermost if-else block to me simplified, using ternary operators (a ? b : c) in the input arguments of the calls instead.

As an additional point, the IVaultCallback::repayCallback calls should be made solely when callbackAddr != address(0) after the top-level if-else clause. A similar optimization can be applied to the BorrowerGateway::processTransfers functions albeit to a lesser degree.

Alleviation (c740f7c6b5ebd365618fd2d7ea77370599e1ca11):

The code has been significantly optimized via the introduction of ternary operators as advised. While certain conditional evaluations could be stored to local bool variables to optimize their legibility (i.e. bool hasCallback = borrowInstructions.callbackAddr != address(0)) by using them in their normal and negated form, we consider this optimization adequately applied to the codebase.

BGY-02C: Redundant Parenthesis Statement

TypeSeverityLocation
Code StyleBorrowerGateway.sol:L242

Description:

The referenced statement is redundantly wrapped in parenthesis (()).

Example:

contracts/peer-to-peer/BorrowerGateway.sol
242uint256 protocolFeeAmount = ((borrowInstructions.collSendAmount) *

Recommendation:

We advise them to be safely omitted, increasing the legibility of the codebase.

Alleviation (c740f7c6b5ebd365618fd2d7ea77370599e1ca11):

The redundant parenthesis statement has been omitted as advised.

BGY-03C: Relocation of Statement

TypeSeverityLocation
Code StyleBorrowerGateway.sol:L236-L238

Description:

The referenced statement is eagerly declared and is solely utilized later in the function's code.

Example:

contracts/peer-to-peer/BorrowerGateway.sol
236uint256 collTokenReceived = IERC20Metadata(loan.collToken).balanceOf(
237 collReceiver
238);
239
240// protocol fees on whole sendAmount
241// this will make calculation of upfrontFee be protocolFeeAmount + (collSendAmount - protocolFeeAmount)*(tokenFee/collUnit)
242uint256 protocolFeeAmount = ((borrowInstructions.collSendAmount) *
243 protocolFee *
244 (loan.expiry - block.timestamp)) /
245 (Constants.BASE * Constants.YEAR_IN_SECONDS);
246
247// should only happen when tenor >> 1 year
248// e.g. at 5% MAX_FEE_PER_ANNUM, tenor still needs to be 20 years
249if (borrowInstructions.collSendAmount < protocolFeeAmount) {
250 revert Errors.InsufficientSendAmount();
251}
252
253if (protocolFeeAmount != 0) {
254 IERC20Metadata(loan.collToken).safeTransferFrom(
255 loan.borrower,
256 IAddressRegistry(addressRegistry).owner(),
257 protocolFeeAmount
258 );
259}
260
261IERC20Metadata(loan.collToken).safeTransferFrom(
262 loan.borrower,
263 collReceiver,
264 borrowInstructions.collSendAmount - protocolFeeAmount
265);
266
267collTokenReceived =
268 IERC20Metadata(loan.collToken).balanceOf(collReceiver) -
269 collTokenReceived;

Recommendation:

We advise it to be relocated right before the SafeERC20::safeTransferFrom operation to the collReceiver, rendering the codebase more concise.

Alleviation (c740f7c6b5ebd365618fd2d7ea77370599e1ca11):

The referenced statement was optimally relocated after the protocol fee has been disbursed, ensuring that it is executed solely when it is expected to be utilized and thus optimizing the failure case gas cost of the function.