In the SellCreditMarket.sol's validateSellCreditMarket function there is an incorrect assumption that prevents loans from being made. As a result, attempts to sell credit that should be successful will fail.
Proof of Concept
The following validation is made in the function when params.creditPositionId != RESERVED_ID:
This, however, may revert wrongly when params.exactAmountIn is set to false. In that scenario, the params.amount is represented as the cash that the borrower will receive and it CAN be less than state.riskConfig.minimumCreditBorrowAToken as the maxCredit derived from params.amount is calculated as follows:
Therefore, params.amount will be scaled up, and as a result the credit that the lender will receive will be more than the state.riskConfig.minimumCreditBorrowAToken.
Thus, the function should not fail when a cashAmountOut, less than state.riskConfig.minimumCreditBorrowAToken, returns a creditAmountIn, more than state.riskConfig.minimumCreditBorrowAToken.
Furthermore, we understand that this is unintended behaviour due to the fact that when params.exactAmountIn is set to true, a credit amount > state.riskConfig.minimumCreditBorrowAToken that returns a cash amount out < state.riskConfig.minimumCreditBorrowAToken won't cause the function to fail.
Tools Used
Manual review
Recommended Mitigation Steps
If params.exactAmountIn is set to false validate that maxCredit is not less than state.riskConfig.minimumCreditBorrowAToken.
Lines of code
https://github.com/code-423n4/2024-06-size/blob/8850e25fb088898e9cf86f9be1c401ad155bea86/src/libraries/actions/SellCreditMarket.sol#L87
Vulnerability details
Impact
In the
SellCreditMarket.sol
'svalidateSellCreditMarket
function there is an incorrect assumption that prevents loans from being made. As a result, attempts to sell credit that should be successful will fail.Proof of Concept
The following validation is made in the function when
params.creditPositionId != RESERVED_ID
:This, however, may revert wrongly when
params.exactAmountIn
is set to false. In that scenario, theparams.amount
is represented as the cash that the borrower will receive and it CAN be less thanstate.riskConfig.minimumCreditBorrowAToken
as themaxCredit
derived fromparams.amount
is calculated as follows:Therefore,
params.amount
will be scaled up, and as a result the credit that the lender will receive will be more than thestate.riskConfig.minimumCreditBorrowAToken
.Thus, the function should not fail when a
cashAmountOut
, less thanstate.riskConfig.minimumCreditBorrowAToken
, returns acreditAmountIn
, more thanstate.riskConfig.minimumCreditBorrowAToken
.Furthermore, we understand that this is unintended behaviour due to the fact that when
params.exactAmountIn
is set to true, a credit amount >state.riskConfig.minimumCreditBorrowAToken
that returns a cash amount out <state.riskConfig.minimumCreditBorrowAToken
won't cause the function to fail.Tools Used
Manual review
Recommended Mitigation Steps
If
params.exactAmountIn
is set to false validate thatmaxCredit
is not less thanstate.riskConfig.minimumCreditBorrowAToken
.Assessed type
Invalid Validation