Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Description
Brief/Intro
A user who tries to create a loan has to choose the loanId. Any user can frontrun this transaction with the same loanId, making the initial user's transaction to revert because his selected loanId is taken.
Vulnerability Details
Each loan has a unique bytes32 identifier named loanId. During the loan creation, each user is asked to provide the loanId that his loan will have.
LoanManager.solfunctioncreateUserLoan( bytes32 loanId, bytes32 accountId, uint16 loanTypeId, bytes32 loanName ) externaloverrideonlyRole(HUB_ROLE) nonReentrant {// check loan types exists, is not deprecated and no existing user loan for same loan idif (!isLoanTypeCreated(loanTypeId)) revert LoanTypeUnknown(loanTypeId);if (isLoanTypeDeprecated(loanTypeId)) revert LoanTypeDeprecated(loanTypeId);@>if (isUserLoanActive(loanId)) revert UserLoanAlreadyCreated(loanId);// create loan UserLoan storage userLoan = _userLoans[loanId];userLoan.isActive =true;userLoan.accountId = accountId;userLoan.loanTypeId = loanTypeId; emit CreateUserLoan(loanId, accountId, loanTypeId, loanName); }
At this point, if there is already a loan with the desired loanId, the transaction reverts. Upon a valid loan creation, a new UserLoan object is created and UserLoan.isActive is set to true.
An attacker can take advantage of this and frontrun all the loan creation transactions (on the chains with a public mempool, like the Ethereum mainnet) and prevent all the users from creating loans.
Impact Details
This is a griefing attack which prevents all users from creating loans. Every transaction will fail because the attacker can frontrun it with the same loanId.