Closed c4-bot-10 closed 2 months ago
Thank you for judging @hansfriese,
Note in Buy credit there is no If and else statement nested so we don't need to check both as already stated above.
if (params.creditPositionId == RESERVED_ID) {
// slither-disable-next-line unused-return
state.createDebtAndCreditPositions({
lender: msg.sender,
borrower: msg.sender,
futureValue: creditAmountIn,
dueDate: block.timestamp + tenor
});
}
state.createCreditPosition({
exitCreditPositionId: params.creditPositionId == RESERVED_ID
? state.data.nextCreditPositionId - 1
: params.creditPositionId,
lender: params.lender,
credit: creditAmountIn
});
with Credit Id - Bypass Check (eventhough we are buying, we can buy below Opening Borrow CR )
if (params.creditPositionId == RESERVED_ID) {
// slither-disable-next-line unused-return
state.createDebtAndCreditPositions({
lender: msg.sender,
borrower: borrower,
futureValue: creditAmountOut,
dueDate: block.timestamp + tenor
});
} else {
state.createCreditPosition({
exitCreditPositionId: params.creditPositionId,
lender: msg.sender,
credit: creditAmountOut
});
}
We should check the OpeningBorrowCr always in BUYcreditMarket regardless of what was used (Credit/Reserve Id). The below allows for a bypass when credit is used
if (params.creditPositionId == RESERVED_ID) {
state.validateUserIsNotBelowOpeningLimitBorrowCR(params.borrower);
}
Lines of code
https://github.com/code-423n4/2024-06-size/blob/8850e25fb088898e9cf86f9be1c401ad155bea86/src/Size.sol#L181-L183 https://github.com/code-423n4/2024-06-size/blob/8850e25fb088898e9cf86f9be1c401ad155bea86/src/Size.sol#L192
Vulnerability details
Impact
The issue lies in the protocol's logic for checking the Credit Ratio (CR) during the purchase of a credit position via the
BuyCreditMarket
function.Specifically:
RESERVED_ID
) is used. However, when a user buys an existing credit position, thecreditPositionId
is set to the old credit position's ID/creates a new one. This allows the user to bypass the CR check and purchase a credit position with a CR close to the liquidation threshold, thus exploiting the system for potential profit by aiming to liquidate soon after purchase.Here's the vulnerability that can be exploited:
Proof of Concept
Exploitation Scenario:
Outcome: Since the
creditPositionId
is notRESERVED_ID
, the checkvalidateUserIsNotBelowOpeningLimitBorrowCR
is bypassed, allowing the user to purchase a position with a dangerously low CR.Potential Consequences
Code Reference:
BuyCreditMarket Function:
Test Case:
buyCreditMarket
function.Tool Used
Manual Code Analysis
Recommended Mitigation Steps
Implement Comprehensive CR Check:
Ensure that the CR is checked for both new and existing credit positions. Update the function to always validate the CR, regardless of the credit position ID.
Example Code Update:
Assessed type
Error