Omniscia Myso Finance Audit
BorrowerGateway Code Style Findings
BorrowerGateway Code Style Findings
BGY-01C: Code Simplification
Type | Severity | Location |
---|---|---|
Gas Optimization | BorrowerGateway.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:
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.collTokenCompartmentAddr295 );296 } else {297 ILenderVaultImpl(lenderVault).transferTo(298 loan.collToken,299 loan.borrower,300 reclaimCollAmount301 );302 }303} else {304 if (305 IAddressRegistry(addressRegistry).whitelistState(306 callbackAddr307 ) != DataTypesPeerToPeer.WhitelistState.CALLBACK308 ) {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.collTokenCompartmentAddr319 );320 IVaultCallback(callbackAddr).repayCallback(loan, callbackData);321 } else {322 ILenderVaultImpl(lenderVault).transferTo(323 loan.collToken,324 callbackAddr,325 reclaimCollAmount326 );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
Type | Severity | Location |
---|---|---|
Code Style | BorrowerGateway.sol:L242 |
Description:
The referenced statement is redundantly wrapped in parenthesis (()
).
Example:
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
Type | Severity | Location |
---|---|---|
Code Style | BorrowerGateway.sol:L236-L238 |
Description:
The referenced statement is eagerly declared and is solely utilized later in the function's code.
Example:
236uint256 collTokenReceived = IERC20Metadata(loan.collToken).balanceOf(237 collReceiver238);239
240// protocol fees on whole sendAmount241// 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 year248// e.g. at 5% MAX_FEE_PER_ANNUM, tenor still needs to be 20 years249if (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 protocolFeeAmount258 );259}260
261IERC20Metadata(loan.collToken).safeTransferFrom(262 loan.borrower,263 collReceiver,264 borrowInstructions.collSendAmount - protocolFeeAmount265);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.