Closed c4-bot-1 closed 4 months ago
https://github.com/code-423n4/2024-06-size/blob/main/src/libraries/LoanLibrary.sol#L182 https://github.com/code-423n4/2024-06-size/blob/main/src/libraries/LoanLibrary.sol#L157
The proportional collateral assigned to CreditPosition may be slightly lower than expected.
If debtPosition.futureValue is not zero(not repaid yet), then the pro-rata collateral assigned to a CreditPosition is
function getCreditPositionProRataAssignedCollateral(State storage state, CreditPosition memory creditPosition) public view returns (uint256) { DebtPosition storage debtPosition = getDebtPosition(state, creditPosition.debtPositionId); uint256 debtPositionCollateral = getDebtPositionAssignedCollateral(state, debtPosition); uint256 creditPositionCredit = creditPosition.credit; uint256 debtPositionFutureValue = debtPosition.futureValue; if (debtPositionFutureValue != 0) { @> return Math.mulDivDown(debtPositionCollateral, creditPositionCredit, debtPositionFutureValue); } else { return 0; } }
And debtPositionCollateral is
debtPositionCollateral
function getDebtPositionAssignedCollateral(State storage state, DebtPosition memory debtPosition) public view returns (uint256) { uint256 debt = state.data.debtToken.balanceOf(debtPosition.borrower); uint256 collateral = state.data.collateralToken.balanceOf(debtPosition.borrower); if (debt != 0) { @> return Math.mulDivDown(collateral, debtPosition.futureValue, debt); } else { return 0; } }
Therefore,
creditPositionProRataAssignedCollateral = debtPositionCollateral * creditPositionCredit / debtPositionFutureValue = (collateral * debtPosition.futureValue / debt) * creditPosition.credit / debtPosition.futureValue = (collateral * debtPosition.futureValue * creditPosition.credit) / (debt * debtPosition.futureValue) = collateral * creditPosition.credit / debt
debtPosition.futureValue is used in both of denominator and nominator. So it may rounds down twice in above calculation.
debtPosition.futureValue
Manual review
function getCreditPositionProRataAssignedCollateral(State storage state, CreditPosition memory creditPosition) public view returns (uint256) { DebtPosition storage debtPosition = getDebtPosition(state, creditPosition.debtPositionId); -- uint256 debtPositionCollateral = getDebtPositionAssignedCollateral(state, debtPosition); ++ uint256 debt = state.data.debtToken.balanceOf(debtPosition.borrower); ++ uint256 collateral = state.data.collateralToken.balanceOf(debtPosition.borrower); uint256 creditPositionCredit = creditPosition.credit; uint256 debtPositionFutureValue = debtPosition.futureValue; -- if (debtPositionFutureValue != 0) { -- return Math.mulDivDown(debtPositionCollateral, creditPositionCredit, debtPositionFutureValue); ++ if (debtPositionFutureValue != 0 && debt != 0) { ++ return Math.mulDivDown(collateral, creditPositionCredit, debt); } else { return 0; } }
Math
Lines of code
https://github.com/code-423n4/2024-06-size/blob/main/src/libraries/LoanLibrary.sol#L182 https://github.com/code-423n4/2024-06-size/blob/main/src/libraries/LoanLibrary.sol#L157
Vulnerability details
Impact
The proportional collateral assigned to CreditPosition may be slightly lower than expected.
Proof of Concept
If debtPosition.futureValue is not zero(not repaid yet), then the pro-rata collateral assigned to a CreditPosition is
And
debtPositionCollateral
isTherefore,
debtPosition.futureValue
is used in both of denominator and nominator. So it may rounds down twice in above calculation.Tools Used
Manual review
Recommended Mitigation Steps
Assessed type
Math