This code is intended to allow users to buy credit on the market. However, there is a logic vulnerability in the code. The main problem of the vulnerability lies in the order of checking the validation conditions and executing the state changes. Specifically, the state change operation executeBuyCreditMarket is executed before the last two validation operations validateUserIsNotBelowOpeningLimitBorrowCR and validateVariablePoolHasEnoughLiquidity.
The vulnerability in this code is that the operation of buying the credit market (state.executeBuyCreditMarket(params)) is performed before all necessary validations are completed. This may lead to unexpected behavior and state changes if the last two validations fail.
The attacker first prepares a normal transaction, setting himself as params.borrower and setting params.creditPositionId to RESERVED_ID.
The attacker then sends this transaction to the contract by calling the contract's buyCreditMarket function.
The validateBuyCreditMarket(params) function is first called to validate the parameters, which pass the validation.
The next call to executeBuyCreditMarket(params) makes the relevant state changes and changes required to buy credit.
After that, the validateUserIsNotBelowOpeningLimitBorrowCR(params.borrower) function is called. If this function fails and throws an error due to a condition related to borrower (such as the borrower exceeds a certain preset borrowing threshold), the execution will stop.
However, at this point the state change via executeBuyCreditMarket(params) has already occurred without checking the borrower's credit limit or whether the contract has sufficient liquidity. Therefore, the attacker's credit limit has been successfully purchased even though their borrowing ratio is illegal.
As a result, the attacker could abuse the borrower parameter to exploit this vulnerability, ignoring borrowing limits and deceiving the contract.
Tools Used
Manual review
Recommended Mitigation Steps
The executeBuyCreditMarket(params) function that performs state-changing operations should only be executed after all necessary validation checks have been successfully completed. This modification ensures that all preconditions are met before any state-changing transactions and operations are executed. Therefore, the order of function calls will be adjusted as follows:
Lines of code
https://github.com/code-423n4/2024-06-size/blob/main/src/Size.sol#L178-L185
Vulnerability details
Impact
This code is intended to allow users to buy credit on the market. However, there is a logic vulnerability in the code. The main problem of the vulnerability lies in the order of checking the validation conditions and executing the state changes. Specifically, the state change operation
executeBuyCreditMarket
is executed before the last two validation operationsvalidateUserIsNotBelowOpeningLimitBorrowCR
andvalidateVariablePoolHasEnoughLiquidity
.Proof of Concept
https://github.com/code-423n4/2024-06-size/blob/main/src/Size.sol#L178-L185
The vulnerability in this code is that the operation of buying the credit market (
state.executeBuyCreditMarket(params)
) is performed before all necessary validations are completed. This may lead to unexpected behavior and state changes if the last two validations fail.params.borrower
and settingparams.creditPositionId
toRESERVED_ID
.buyCreditMarket
function.validateBuyCreditMarket(params)
function is first called to validate the parameters, which pass the validation.executeBuyCreditMarket(params)
makes the relevant state changes and changes required to buy credit.validateUserIsNotBelowOpeningLimitBorrowCR(params.borrower)
function is called. If this function fails and throws an error due to a condition related toborrower
(such as the borrower exceeds a certain preset borrowing threshold), the execution will stop.executeBuyCreditMarket(params)
has already occurred without checking theborrower
's credit limit or whether the contract has sufficient liquidity. Therefore, the attacker's credit limit has been successfully purchased even though their borrowing ratio is illegal.borrower
parameter to exploit this vulnerability, ignoring borrowing limits and deceiving the contract.Tools Used
Manual review
Recommended Mitigation Steps
The
executeBuyCreditMarket(params)
function that performs state-changing operations should only be executed after all necessary validation checks have been successfully completed. This modification ensures that all preconditions are met before any state-changing transactions and operations are executed. Therefore, the order of function calls will be adjusted as follows:Assessed type
Invalid Validation